package com.guit.hrms.manager;

import com.guit.hrms.po.interview.Offer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DynamicTaskManager {

    private final TaskScheduler taskScheduler;
    private final Map<Integer, TaskInfo> scheduledTasks = new ConcurrentHashMap<>();
    private static final DateTimeFormatter CRON_FORMATTER = DateTimeFormatter.ofPattern("ss mm HH dd MM ?");
    private static final DateTimeFormatter LOG_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    public DynamicTaskManager(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    public void addTask(Integer offerId, Offer offer, Runnable task) {
        try {
            // 如果已存在任务，先移除
            removeTask(offerId);
            
            LocalDateTime now = LocalDateTime.now();
            // 验证过期时间
            if (offer.getExpiryTime().isBefore(now)) {
                log.info("Offer已过期，直接执行任务。OfferId: {}，过期时间: {}", 
                        offerId, offer.getExpiryTime().format(LOG_FORMATTER));
                task.run(); // 直接执行任务
                return;
            }
            
            // 创建带有错误处理的任务包装
            Runnable wrappedTask = () -> {
                try {
                    log.info("开始执行 Offer 过期处理任务，OfferId: {}", offerId);
                    task.run();
                    log.info("Offer 过期处理任务执行完成，OfferId: {}", offerId);
                } catch (Exception e) {
                    log.error("Offer 过期处理任务执行失败，OfferId: {}，原因: {}", offerId, e.getMessage());
                } finally {
                    // 任务执行完成后自动清理
                    scheduledTasks.remove(offerId);
                }
            };

            // 创建cron表达式并调度任务
            String cronExpression = offer.getExpiryTime().format(CRON_FORMATTER);
            log.info("正在调度 Offer 任务，OfferId: {}，执行时间: {}", 
                    offerId, offer.getExpiryTime().format(LOG_FORMATTER));
            
            ScheduledFuture<?> scheduledTask = taskScheduler.schedule(
                wrappedTask, 
                new CronTrigger(cronExpression)
            );
            
            // 保存任务信息
            scheduledTasks.put(offerId, new TaskInfo(scheduledTask, offer.getExpiryTime()));
            log.info("Offer 任务调度成功，OfferId: {}，当前活跃任务数: {}", offerId, scheduledTasks.size());
        } catch (Exception e) {
            log.error("Offer 任务调度失败，OfferId: {}，原因: {}", offerId, e.getMessage());
            throw new RuntimeException("任务调度失败", e);
        }
    }

    public void removeTask(Integer offerId) {
        TaskInfo taskInfo = scheduledTasks.remove(offerId);
        if (taskInfo != null && taskInfo.getScheduledFuture() != null) {
            taskInfo.getScheduledFuture().cancel(false);
            log.info("已取消 Offer 任务，OfferId: {}，原定执行时间: {}", 
                    offerId, taskInfo.getExpiryTime().format(LOG_FORMATTER));
        }
    }

    /**
     * 检查是否已调度任务
     */
    public boolean hasScheduledTask(Integer offerId) {
        TaskInfo taskInfo = scheduledTasks.get(offerId);
        if (taskInfo != null) {
            boolean isValid = !taskInfo.getScheduledFuture().isCancelled() && 
                            !taskInfo.getScheduledFuture().isDone();
            if (!isValid) {
                scheduledTasks.remove(offerId);
            }
            return isValid;
        }
        return false;
    }

    /**
     * 获取活跃的任务数量
     */
    public int getActiveTaskCount() {
        // 清理已完成或已取消的任务
        scheduledTasks.entrySet().removeIf(entry -> {
            ScheduledFuture<?> future = entry.getValue().getScheduledFuture();
            return future.isCancelled() || future.isDone();
        });
        return scheduledTasks.size();
    }

    /**
     * 清理无效的任务
     */
    public void cleanupInvalidTasks(List<Offer> activeOffers) {
        LocalDateTime now = LocalDateTime.now();
        
        // 创建活跃offer的ID集合
        Set<Integer> activeOfferIds = activeOffers.stream()
                .map(Offer::getId)
                .collect(Collectors.toSet());

        // 清理不在活跃列表中或已过期的任务
        scheduledTasks.entrySet().removeIf(entry -> {
            Integer offerId = entry.getKey();
            TaskInfo taskInfo = entry.getValue();
            
            boolean shouldRemove = !activeOfferIds.contains(offerId) || 
                                 taskInfo.getExpiryTime().isBefore(now) ||
                                 taskInfo.getScheduledFuture().isCancelled() ||
                                 taskInfo.getScheduledFuture().isDone();
            
            if (shouldRemove) {
                removeTask(offerId);
                log.info("清理无效任务，OfferId: {}，过期时间: {}", 
                        offerId, taskInfo.getExpiryTime().format(LOG_FORMATTER));
            }
            
            return shouldRemove;
        });
    }

    /**
     * 任务信息内部类
     */
    @Data
    @AllArgsConstructor
    private static class TaskInfo {
        private final ScheduledFuture<?> scheduledFuture;
        private final LocalDateTime expiryTime;
    }
}
